
module platform
(
   // 50Mhz input
   input              CLK,
   // DDR interface
   inout     [14:0]   DDR_addr,
   inout     [2:0]    DDR_ba,
   inout              DDR_cas_n,
   inout              DDR_ck_n,
   inout              DDR_ck_p,
   inout              DDR_cke,
   inout              DDR_cs_n,
   inout     [3:0]    DDR_dm,
   inout     [31:0]   DDR_dq,
   inout     [3:0]    DDR_dqs_n,
   inout     [3:0]    DDR_dqs_p,
   inout              DDR_odt,
   inout              DDR_ras_n,
   inout              DDR_reset_n,
   inout              DDR_we_n,
   // FIXED_IO interface
   inout              FIXED_IO_ddr_vrn,
   inout              FIXED_IO_ddr_vrp,
   inout     [53:0]   FIXED_IO_mio,
   inout              FIXED_IO_ps_clk,
   inout              FIXED_IO_ps_porb,
   inout              FIXED_IO_ps_srstb,
   //IIS
   output             IIS_SCLK,
   output             IIS_LRCK,
   output             IIS_DATA
);

//*****************************************************************************
// Parameters
//*****************************************************************************

//*****************************************************************************
// Reg control
//*****************************************************************************
reg  [11:0] sys_rst_cnt;
reg         sys_rst;
wire        reg_ctrl_clk;
wire        reg_ctrl_rst;
wire [1:0]  NULL_2BITS;

wire        clk_100m;
wire        clk_24m;
wire        clk_74p25m;
wire        clk_371p25m;
   
wire        server_uart_rx;
wire        server_uart_tx;
wire        clk_3p072m;

//*****************************************************************************
// Ifs
//*****************************************************************************
if_reg_ctrl #(.ADDR_WID(14)) host_reg_ctrl();
if_reg_ctrl #(.ADDR_WID(8)) slave_reg_ctrl [0:3]();
   
//*****************************************************************************
// Maps
//*****************************************************************************
system u_system
(
   // DDR interface
   .DDR_addr               ( DDR_addr ),
   .DDR_ba                 ( DDR_ba ),
   .DDR_cas_n              ( DDR_cas_n ),
   .DDR_ck_n               ( DDR_ck_n ),
   .DDR_ck_p               ( DDR_ck_p ),
   .DDR_cke                ( DDR_cke ),
   .DDR_cs_n               ( DDR_cs_n ),
   .DDR_dm                 ( DDR_dm ),
   .DDR_dq                 ( DDR_dq ),
   .DDR_dqs_n              ( DDR_dqs_n ),
   .DDR_dqs_p              ( DDR_dqs_p ),
   .DDR_odt                ( DDR_odt ),
   .DDR_ras_n              ( DDR_ras_n ),
   .DDR_reset_n            ( DDR_reset_n ),
   .DDR_we_n               ( DDR_we_n ),
   // FIXED_IO interface
   .FIXED_IO_ddr_vrn       ( FIXED_IO_ddr_vrn ),
   .FIXED_IO_ddr_vrp       ( FIXED_IO_ddr_vrp ),
   .FIXED_IO_mio           ( FIXED_IO_mio ),
   .FIXED_IO_ps_clk        ( FIXED_IO_ps_clk ),
   .FIXED_IO_ps_porb       ( FIXED_IO_ps_porb ),
   .FIXED_IO_ps_srstb      ( FIXED_IO_ps_srstb ),
   // Clock
   .CLK_100M               ( clk_100m ),
   .CLK_24M                ( clk_24m ),
   // Server UART
   .SERVER_UART_rxd        ( server_uart_rx ),
   .SERVER_UART_txd        ( server_uart_tx ),
   .HOST_UART_rxd          ( server_uart_tx ),
   .HOST_UART_txd          ( server_uart_rx ),
   // Reg control
   .REG_CTRL_addr          ( {host_reg_ctrl.addr, NULL_2BITS} ),
   .REG_CTRL_clk           ( reg_ctrl_clk ),
   .REG_CTRL_din           ( host_reg_ctrl.wdata ),
   .REG_CTRL_dout          ( host_reg_ctrl.rdata ),
   .REG_CTRL_en            ( host_reg_ctrl.en ),
   .REG_CTRL_rst           ( reg_ctrl_rst ),
   .REG_CTRL_we            ( host_reg_ctrl.we )
);

//*****************************************************************************
// System reset
//*****************************************************************************
always @(posedge reg_ctrl_clk)
begin
   sys_rst_cnt <= sys_rst_cnt + ~&sys_rst_cnt;
end

always @(posedge reg_ctrl_clk)
begin
   if(&sys_rst_cnt)
      sys_rst <= 1'b0;
   else
      sys_rst <= 1'b1;
end
   
//*****************************************************************************
// Reg control
//*****************************************************************************
reg_arbiter
#(
   .SLAVE_CNT              ( 4 )
)
u_reg_arbiter
(
   .clk                    ( reg_ctrl_clk ),
   .reg_if_i               ( host_reg_ctrl ),
   .reg_if_o               ( slave_reg_ctrl )
);
   
//*****************************************************************************
// Hard reg
//*****************************************************************************
hard_reg u_hard_reg
(
   .reset                  ( sys_rst ),
   .reg_clk                ( reg_ctrl_clk ),
   .reg_if                 ( slave_reg_ctrl[0] )
);
   
//*****************************************************************************
// Clock wrapper
//*****************************************************************************
clock_wrapper u_clock_wrapper
(
   .clk_50m               ( CLK ),
   .clk_3p072m            ( clk_3p072m )
);
   
//*****************************************************************************
// Audio wrapper
//*****************************************************************************
audio_wrapper u_audio_wrapper
(
   .reset                 ( sys_rst ),
   .reg_clk               ( reg_ctrl_clk ),
   .reg_if                ( slave_reg_ctrl[1] ),
   .clk_3p072m            ( clk_3p072m ),
   .iis_sclk              ( IIS_SCLK ),
   .iis_lrck              ( IIS_LRCK ),
   .iis_data              ( IIS_DATA )
); 

endmodule
